// Copyright 2021 by 马万里. All rights reserved.
// 开发团队 ：   鸡中之霸
// 开发人员 ：   马万里
// 开发时间 ：   2021/3/2 15:15
// 文件名称 ：   product.go
// 工程名称 ：   seckill
// 开发工具 ：   GoLand
//

package repositories

import (
	"backend/common"
	"backend/datamodels"
	"database/sql"
)

// IProduct: 获取数据的接口
type IProduct interface {
	// 连接数据
	Conn() (err error)                                       // 连接数据库
	Insert(p *datamodels.Product) (n int64, err error)       // 插入数据
	Delete(id int64) bool                                    // 删除数据
	Update(p *datamodels.Product) (err error)                // 更新数据
	SelectByKey(id int64) (p *datamodels.Product, err error) // 查询数据
	SelectAll() (ps []*datamodels.Product, err error)        // 查询所有数据
}

// 实现接口的结构体
type ProductManager struct {
	table     string
	mysqlConn *sql.DB
}

// 工厂方法
func NewProductManager(table string, db *sql.DB) IProduct {
	return &ProductManager{
		table:     table,
		mysqlConn: db,
	}
}

// 获取数据库连接
func (pm *ProductManager) Conn() (err error) {

	if pm.mysqlConn == nil {
		pm.mysqlConn, err = common.NewMysqlConn()
		if err != nil {
			return
		}
	}
	if pm.table == "" {
		pm.table = "product"
	}
	return
}

// 插入数据
func (pm *ProductManager) Insert(p *datamodels.Product) (id int64, err error) {

	// 判断是否连接成功
	if err := pm.Conn(); err != nil {
		return 0, err
	}

	// 执行插入语句
	//sql := "INSERT INTO product (`productName`, `productNum`, `productImage`, `productUrl`) VALUES (?,?,?,?)"
	sqlStr := "INSERT product SET productName=?, productNum=?, productImage=?, productUrl=?"
	stmt, err := pm.mysqlConn.Prepare(sqlStr)
	defer stmt.Close()
	if err != nil {
		return 0, err
	}
	result, err := stmt.Exec(p.ProductName, p.ProductNum, p.ProductImage, p.ProductUrl)
	if err != nil {
		return 0, err
	}
	return result.LastInsertId()
}

// 删除数据
func (pm *ProductManager) Delete(id int64) bool {
	// 判断是否连接成功
	if err := pm.Conn(); err != nil {
		return false
	}
	sqlStr := "DELETE FROM product WHERE ID=?"
	stmt, err := pm.mysqlConn.Prepare(sqlStr)
	defer stmt.Close()
	if err != nil {
		return false
	}
	_, err = stmt.Exec(id)
	if err != nil {
		return false
	}
	return true
}

// 商品更新
func (pm *ProductManager) Update(p *datamodels.Product) (err error) {
	// 判断是否连接成功
	if err := pm.Conn(); err != nil {
		return err
	}
	sqlStr := "UPDATE product SET productName=?, productNum=?, productImage=?, productUrl=? WHERE ID=?"
	stmt, err := pm.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return err
	}
	defer stmt.Close()
	_, err = stmt.Exec(p.ProductName, p.ProductNum, p.ProductImage, p.ProductUrl, p.ID)
	return err
}

// 查询单条记录
func (pm *ProductManager) SelectByKey(id int64) (p *datamodels.Product, err error) {
	// 判断是否连接成功
	if err = pm.Conn(); err != nil {
		return &datamodels.Product{}, err
	}
	sqlStr := "SELECT * FROM product WHERE ID=?"
	stmt, err := pm.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return &datamodels.Product{}, err
	}
	defer stmt.Close()
	rows, err := stmt.Query(id)
	if err != nil {
		return &datamodels.Product{}, err
	}
	defer rows.Close()
	data := common.GetResultRow(rows)
	if len(data) == 0 {
		return &datamodels.Product{}, err
	}
	p = new(datamodels.Product)
	common.DataToStructByTagSql(data, p)
	return
}

// 查询多条记录
func (pm *ProductManager) SelectAll() (ps []*datamodels.Product, err error) {
	// 判断是否连接成功
	if err = pm.Conn(); err != nil {
		return nil, err
	}
	sqlStr := "SELECT * FROM product"
	stmt, err := pm.mysqlConn.Prepare(sqlStr)
	if err != nil {
		return nil, err
	}
	defer stmt.Close()
	rows, err := stmt.Query()
	if err != nil {
		return nil, err
	}
	defer rows.Close()
	results := common.GetResultRows(rows)
	if len(results) == 0 {
		return nil, err
	}
	for _, data := range results {
		product := &datamodels.Product{}
		common.DataToStructByTagSql(data, product)
		ps = append(ps, product)
	}
	return
}

